﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using Sokoban.Model;
using Sokoban.ViewModel.Boxes;
using System.Windows.Media;
using Brushes = System.Windows.Media.Brushes;
using System.IO;
using System.Windows;

namespace Sokoban.ViewModel
{
    class EditorViewModel : INotifyPropertyChanged
    {
        public int playerRow = -1;
        public int playerCol = -1;
        public BoxViewModel[,] BoxMatrix;
        public int Rows { get; private set; }
        public int Cols { get; private set; }        
        public event PropertyChangedEventHandler PropertyChanged;
        public EditorViewModel()
        {   
        }
        public EditorViewModel(int maxrow, int maxcol)
        {
            BoxMatrix = new BoxViewModel[maxrow, maxcol];
            this.Rows = maxrow;
            this.Cols = maxcol;
            for (int i = 0; i < Rows; i++)
            {
                for (int j = 0; j < Cols; j++)
                {
                    var bvm = new BoxViewModel();
                    bvm.Box = new Wall(i,j);
                    bvm.Name = "Wall";
                    BoxMatrix[i, j] = bvm;
                }
            }
        }
        public void GridClicked(string selected, int row, int col)
        {
            switch (selected)
            {
                case "Player":
                    if (playerRow == -1)
                    {
                        BoxMatrix[row, col].Box = new Player(row, col);
                        playerRow = row;
                        playerCol = col;
                    }
                    else
                    {
                        BoxMatrix[playerRow, playerCol].Box = new Empty(playerRow, playerCol);
                        BoxMatrix[row, col].Box = new Player(row, col);
                        playerRow = row;
                        playerCol = col;
                    }
                    break;
                case "Empty":
                    BoxMatrix[row, col].Box = new Empty(row, col);
                    break;
                case "Wall":
                    BoxMatrix[row, col].Box = new Wall(row, col);
                    break;
                case "Box":
                    BoxMatrix[row, col].Box = new Box(row, col);
                    break;
                case "Goal":
                    BoxMatrix[row, col].Box = new Goal(row, col);
                    break;
                default:
                    BoxMatrix[row, col].Box = new Empty(row, col);
                    break;
            }            
        }
        public void LoadMap(string path)
        {
            var map = MapReader.ReadMap(path);

            this.Rows = map.GridMatrix.GetLength(0);
            this.Cols = map.GridMatrix.GetLength(1);
            BoxMatrix = new BoxViewModel[Rows, Cols];

            for (int y = 0; y < Rows; y++)
            {
                for (int x = 0; x < Cols; x++)
                {
                    var bvm = new BoxViewModel();
                    bvm.Box = map.GridMatrix[y, x];
                    bvm.Name = map.GridMatrix[y, x].ToString();
                    BoxMatrix[y, x] = bvm;
                    if (bvm.Box is Player)
                    {
                        playerRow = y;
                        playerCol = x;
                    }
                }
            }
        }
        public void SaveMap()
        {
            string mapName = "custom" + DateTime.Now.Year+DateTime.Now.Month+DateTime.Now.Day + '_' + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + ".xml";
            var map = new Map(mapName, Rows, Cols);

            for (int r = 0; r < Rows; r++)
            {
                for (int c = 0; c < Cols; c++)
                {
                    map.GridMatrix[r, c] = BoxMatrix[r, c].Box;
                }
            }

            MapWriter.SerializeMap(map, mapName);
        }
        public bool CheckPlayer()
        {
            int playercount = 0;
            for (int r = 0; r < Rows; r++)
                for (int c = 0; c < Cols; c++)
                    if (BoxMatrix[r, c].Box is Player)
                        playercount++;
            return playercount==1;
        }
        public bool CheckBoxAndGoals()
        {
            int boxCount = 0;
            int goalCount = 0;
            for (int r = 0; r < Rows; r++)
                for (int c = 0; c < Cols; c++)
                    if (BoxMatrix[r, c].Box is Box)
                        boxCount++;
                    else
                        if (BoxMatrix[r, c].Box is Goal)
                            goalCount++;
            return ((goalCount > 0) && (goalCount <= boxCount));
        }
        public bool CheckMapSolvable()
        {
            Solver solveThisMap = new Solver(BoxMatrix, 10, 10, 200);
            return solveThisMap.CanBeSolvedThisMap();
        }
    }

    //public class EditorBoxViewModel : INotifyPropertyChanged
    //{
    //    public string Name
    //    {
    //        get { return myName; }
    //        set
    //        {
    //            myName = value;
    //            if (PropertyChanged != null)
    //            {
    //                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
    //            }
    //            switch (Name)
    //            {
    //                case "Player":
    //                    BackgroundColor = Brushes.Blue;
    //                    break;
    //                case "Empty":
    //                    BackgroundColor = Brushes.Beige;
    //                    break;
    //                case "Wall":
    //                    BackgroundColor = Brushes.Black;
    //                    break;
    //                case "Box":
    //                    BackgroundColor = Brushes.Brown;
    //                    break;
    //                case "Goal":
    //                    BackgroundColor = Brushes.Yellow;
    //                    break;
    //                default:
    //                    BackgroundColor = Brushes.DarkOrange;
    //                    break;
    //            }
    //        }
    //    }

    //    public SolidColorBrush BackgroundColor
    //    {
    //        get { return myBackgroundColor; }
    //        set
    //        {
    //            myBackgroundColor = value;

    //            if (PropertyChanged != null)
    //            {
    //                PropertyChanged(this, new PropertyChangedEventArgs("BackgroundColor"));
    //            }
    //        }

    //    }

    //    public AbstractBox Box
    //    {
    //        get { return myBox; }
    //        set
    //        {
    //            myBox = value;
    //            Name = value.ToString();
    //        }
    //    }

    //    public event PropertyChangedEventHandler PropertyChanged;

    //    private string myName;
    //    private AbstractBox myBox;
    //    private SolidColorBrush myBackgroundColor;
    //}
}
